package own.stu.jobgib.playown.netty.im;

import lombok.AllArgsConstructor;
import lombok.Data;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

public class Test {

    /*static ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(2);

    static {

        executor.submit(() -> {
            int i = 0;
            for (; i < 10; i++) {
                System.out.println("---> " + i);
                try {
                    TimeUnit.MILLISECONDS.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
    }*/

    public static void main(String[] args) throws InterruptedException {
        Map<String, OnThread> map = new HashMap<>();
        ThreadFactory threadFactory = new ThreadFactory() {

            private AtomicInteger idGener = new AtomicInteger();

            @Override
            public Thread newThread(@NotNull Runnable r) {
                return new OnThread(r, idGener.incrementAndGet() + "");
            }
        };

        Scanner scanner = new Scanner(System.in);

        for (int i = 0; i < 4; i++) {
            Thread thread = threadFactory.newThread(new Run(scanner));
            map.put(thread.getName(), (OnThread) thread);
            thread.start();
        }

        System.out.println("all thread wait, waken up thread: ");
        String line = null;
        while ((line = scanner.nextLine()) != null) {

            OnThread thread = map.get(line);
            if (thread != null) {
                System.out.println("await thread: " + thread.getName());
                Thread.currentThread().join();
                thread.action.awake();
            } else {
                System.out.println(line);
            }

            if ("quit".equals(line)) {
                break;
            }
        }
        scanner.close();


    }

    @Data
    static class OnThread extends Thread {
        private Action action;

        public OnThread() {
            super();
            action = new Action(this);
        }

        public OnThread(Runnable runnable, String name) {
            super(runnable, name);
            action = new Action(this);
        }
    }

    @Data
    static class Action {
        boolean wait = true;

        Thread thread;

        public Action(Thread thread) {
            this.thread = thread;
        }

        //boolean run;
        public void awake() {
            wait = false;
            thread.interrupt();
        }
    }

    @Data
    @AllArgsConstructor
    static class Run implements Runnable {

        protected final Logger logger = LoggerFactory.getLogger(getClass().getName());

        //        private Action action;
        private Scanner scanner;

        @Override
        public void run() {
            OnThread thread = (OnThread) Thread.currentThread();
            Action action = thread.action;
            String line = null;
            while (true) {
                do {
                    try {
                        TimeUnit.SECONDS.sleep(1);
                    } catch (InterruptedException e) {
                        logger.error("interrupted : {}", thread.getName());
                    }
                } while (action.wait);

                while ((line = scanner.nextLine()) != null) {
                    System.out.println(line);
                    logger.info("{} : {}", thread.getName(), line);
                    if ("quit".equals(line)) {
                        action.wait = true;
                        break;
                    }
                }
            }
        }
    }

    public static void main2(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String line = null;
        while ((line = scanner.nextLine()) != null) {
            System.out.println(line);
            if ("quit".equals(line)) {
                break;
            }
        }
        scanner.close();
//        executor.shutdown();
    }
}
